package org.fujene.memoryblock.keyvalue;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import org.fujene.constants.Constants;
import org.fujene.memoryblock.MemoryBlock;
import org.fujene.structure.LookupPointer;
import org.fujene.toolbox.ByteConverter;

public class KeyValueBlock extends MemoryBlock{
	public static final int OPT_LEN = 0;
	public static final int OPTSIZE = 1;

	public KeyValueBlock(ByteBuffer block, int bodySize, int ID, int repBlock){
		super(block, bodySize, ID, Constants.MEMORY_TYPE_INVINDEX, repBlock);
	}

	public KeyValueBlock(ByteBuffer existingBody){
		super(existingBody);
	}

	public KeyValuePackage read(int ptr){
		long key = getLong(ptr, LONG);
		ptr += LONG;
		long value = getLong(ptr, LONG);
		ptr += LONG;
		LookupPointer next = getPointer(ptr, PTR);
		KeyValuePackage pkg = KeyValuePackage.getPackage(key, value, next);

		return pkg;
	}

	public int write(int ptr, KeyValuePackage pkg){
		setLong(ptr, LONG, pkg.getKey());
		ptr += LONG;
		setLong(ptr, LONG, pkg.getValue());
		ptr += LONG;
		setPointer(ptr, PTR, pkg.getNext());
		
		return ptr + LONG;
	}

	public void resetPointer(int ptr, LookupPointer newPtr){
		store(newPtr.toBytes(), ptr);
	}

	public synchronized int allocate(){
		int newSize = LONG * 2; // newest director
		if(bodyVacancy < newSize) return -1;
		bodyVacancy -= newSize;
		option[OPT_LEN]++;
		return bodySize - bodyVacancy - newSize;
	}

	public int length(){
		return LONG * 2;
	}

	@Override
	public int getOptionSize(){
		return OPTSIZE;
	}

	@Override
	public byte[] getOptionByteStream(){
		ByteArrayOutputStream stream = new ByteArrayOutputStream();

		for(int i = 0; i < OPTSIZE; i++){
			try{
				stream.write(ByteConverter.intToByte(option[i], 4));
			}catch(IOException e){}
		}

		return stream.toByteArray();
	}

	@Override
	public int getOption(int index){
		if(index >= OPTSIZE) return -1;
		return option[index];
	}

	@Override
	public void setOption(int index, int value){
		if(index >= OPTSIZE) return;
		option[index] = value;
	}

	@Override
	public String getClassName(){
		return "KeyValue";
	}
}
